package controller;

import dao.elasticsearch.KnowledgeInformationMapper;
import model.elasticsearch.KnowledgeInformation;
import model.value.WordClickCount;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.DisMaxQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import service.PinyinWordService;
import top.swimmer.provider.api.inner.PinyinWordInnerService;
import util.ResponseUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

import static org.elasticsearch.index.query.QueryBuilders.*;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
import static util.Utils.isCollectionEmpty;

/**
 * Created by xiaoyou on 16-6-26.
 */
@Controller
@RequestMapping("/elasticsearch")
public class BaseController {

    @Resource(name = "knowledgeInformationMapper")
    KnowledgeInformationMapper knowledgeInformationMapper;

    @Resource(name = "pinyinWordService")
    PinyinWordService pinyinWordService;

    @Resource(name = "swimmer.pinyinWordInnerService")
    PinyinWordInnerService pinyinWordInnerService;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String searchPage(HttpServletResponse response) throws Exception {
        pinyinWordInnerService.analyzeSearch("shoujih");
        return "search";
    }

    @RequestMapping(value = "/analyze", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST)
    public void search(HttpServletResponse response, @RequestBody Map<String, String> map) throws Exception {
        String input = map.get("input");
        List<List<WordClickCount>> results = pinyinWordService.analyzeSearch(input);
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        Set<String> content = new HashSet<>();
        Set<String> must = new HashSet<>();
        StringBuilder sb = new StringBuilder("");
        Double matchCount = 0.0;
        for (List<WordClickCount> son : results) {
            if (!isCollectionEmpty(son) && son.size() == 1) {
//                must.add(son.get(0).getWord());
            boolQueryBuilder.must(termQuery("pushContent", son.get(0).getWord()));
                continue;
            }
            matchCount += 1.0;
            for (WordClickCount clickCount : son) {
                sb.append(clickCount.getWord());
                content.add(clickCount.getWord());
            }
        }

        Double total = Double.valueOf(content.size());

        int minimumMatch = matchCount.equals(total) ? 99 : (int) (matchCount / total * 100) + 1;
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        boolQueryBuilder.must(termQuery("cityCode", "110000"));
//        if (!isCollectionEmpty(must)) {
//            boolQueryBuilder.must(termsQuery("pushContent", must));
//        }

        searchSourceBuilder.query(boolQueryBuilder);
        if (total != 0) {
            searchSourceBuilder.postFilter(multiMatchQuery(sb.toString(), "pushContent").minimumShouldMatch(minimumMatch + "%"));
        }
        searchSourceBuilder.highlight(
                new HighlightBuilder().field("pushContent").preTags("@preTag@").postTags("@postTag@")
        );
        searchSourceBuilder.from(0).size(15).sort("_score", SortOrder.DESC).sort("clicks", SortOrder.DESC);

        final List<KnowledgeInformation> knowledgeInformation = knowledgeInformationMapper.search(searchSourceBuilder);
        ResponseUtils.writeSuccessResponse(response, new ArrayList<String>(){{
            for (KnowledgeInformation entity : knowledgeInformation) {
                add(entity.getPushContent());
            }
        }});
    }
}
